package com.jinhua.mybatis.util;


import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
import java.util.regex.Pattern;


/**
 * mybatis的更新构建的util
 */

public class MybatisPlusBuild {


	private final String ____EQ____ = "=";
	private final String ____NEQ____ = "!=";
	private final String ____GT____ = ">";
	private final String ____GTE____ = ">=";
	private final String ____LT____ = "<";
	private final String ____LTE____ = "<=";
	private final String ____LIKE____ = "LIKE";
	private final String ____OR____ = " OR ";
	private final String ____AND____ = " AND ";
	private final String ____ISNULL____ = "IS";
	private final String ____ISNOTNULL____ = "IS NOT";
	private final String ____GROUPBEFORE____ = " (";
	private final String ____GROUPAFTER____ = ") ";
	private final String ____LIKE_SIGN____ = "%";
	private final String ____SPLIT_SIGN____ = ",";
	private final String ____SELECT____ = "SELECT";
	private final String ____LIMIT____ = " LIMIT %d,%d";
	private final String ____WHERE____ = " WHERE ";
	private final String ____GROUPBY____ = " GROUP BY %s";
	private final String ____ORDERBY____ = " ORDER BY %s";
	private final String ____BETWEEN____ = " %s BETWEEN  %s AND %s";
	private final String ____NULL____ = "NULL";
	private final String ____IN____ = " %s IN ( %s )";
	private final String ____SUM____ = " sum(%s) AS %s";
	private final String ____NOT_IN____ = " %s NOT IN ( %s )";
	private final String ____EXTRA_WHERE____ = " WHERE  LIMIT";

	private final String ____EMPTY____ = "";
	private final String ____BLANK____ = " ";
	private final Map<String, FieldColumn> ____paramCache____ = new ConcurrentHashMap<>();
	/***防止查询单个增加page条件**/
	private final Pattern ____pattern____ = Pattern.compile("LIMIT[ ,\\d]+LIMIT[ ,\\d]+$");
	private final DateTimeFormatter ____dateTimeFormatter____ = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
	private final DateTimeFormatter ____dateFormatter____ = DateTimeFormatter.ofPattern("yyyy-MM-dd");
	private final DateTimeFormatter ____timeFormatter____ = DateTimeFormatter.ofPattern("HH:mm:ss");
	/**
	 * 根据列名获取get方法的缓存
	 */
	private final Map<String, String> ____filed2GetMethodNameCache____ = new ConcurrentHashMap<>();
	private Boolean ____isWipeWhereFlag____ = Boolean.TRUE;
	private StringBuilder ____sqlConditionBuild____ = new StringBuilder(____WHERE____);
	private StringBuilder ____sqlAssigmentBuild____ = new StringBuilder();
	private Class ____buildClass____;
	private String ____countColumn____ = "*";
	private ThreadLocal<Boolean> ____useCache____ = ThreadLocal.withInitial(() -> Boolean.FALSE);

	public MybatisPlusBuild(Class buildClass) {
		this.____buildClass____ = buildClass;
	}


	protected MybatisPlusBuild() {
		this.____buildClass____ = this.getClass();
	}


	public <____T____, ____R____> MybatisPlusBuild sum(ColumnName<____T____, ____R____>... columns) {
		Objects.requireNonNull(columns);
		for (ColumnName column : columns) {
			FieldColumn fieldColumn = getColumnName(column);
			if (fieldColumn.isEmpty()) {
				continue;
			}
			if (____sqlAssigmentBuild____.length() > 1) {
				assignmentAppend(____SPLIT_SIGN____);
			}
			assignmentAppend(String.format(____SUM____, fieldColumn.getColumnName(), fieldColumn.getField().getName()));
		}


		return this;
	}

	public String getSumSql(String sql) {

		String assignmentSql = assignmentBuild();
		if (assignmentSql.isEmpty()) {
			return sql;
		}

		String replaceReg = assignmentSql.replaceAll("sum\\(", "`").
			replaceAll("\\)", "`").replaceAll(____SPLIT_SIGN____,
			"|").trim();

		//去除多个,
		String newSelectSql = sql.replaceAll(replaceReg.trim(), ____EMPTY____).
			replaceAll("(,\\s?){2}", ____SPLIT_SIGN____);

		if (newSelectSql.length() > ____SELECT____.length()) {
			newSelectSql = newSelectSql.substring(____SELECT____.length());
			//防止两个sum没有,
			if (!newSelectSql.trim().startsWith(____SPLIT_SIGN____)) {
				newSelectSql = ____SPLIT_SIGN____ + newSelectSql;
			}
		}
		//替除多余的,
		newSelectSql=newSelectSql.replaceAll(",\\s+FROM"," FROM");


		return ____SELECT____ + assignmentSql + newSelectSql;


	}


	/**
	 * 等于
	 *
	 * @param column 列表名
	 * @param val    值
	 * @return
	 */
	public <____T____, ____R____> MybatisPlusBuild eq(ColumnName<____T____, ____R____> column, Object val) {
		link(column, ____EQ____, val);
		return this;
	}

	/**
	 * /**
	 * 运算
	 *
	 * @param column       列表名
	 * @param arithmetic   算法
	 * @param assignColumn 赋值的列表名
	 * @param val          值
	 * @return
	 */
	public <____T____, ____R____> MybatisPlusBuild arith(ColumnName<____T____, ____R____> column, Arithmetic arithmetic,
														 ColumnName<____T____, ____R____> assignColumn, Object val) {
		Objects.requireNonNull(arithmetic);
		Objects.requireNonNull(val);
		Objects.requireNonNull(column);
		Objects.requireNonNull(assignColumn);

		String columnName = getColumnName(column).getColumnName();

		if (columnName.isEmpty()) {
			return this;
		}
		String assignColumnName = getColumnName(assignColumn).getColumnName();

		if (assignColumnName.isEmpty()) {
			return this;
		}
		if (____sqlAssigmentBuild____.length() > 1) {
			assignmentAppend(____SPLIT_SIGN____);
		}
		//先连接变量值
		assignmentAppend("`");
		assignmentAppend(columnName);
		assignmentAppend("` ");
		assignmentAppend(____EQ____);
		assignmentAppend(" `");
		assignmentAppend(assignColumnName);
		assignmentAppend("` ");
		// 连接右边赋值
		assignmentAppend(arithmetic.getSymbol());
		assignmentAppend(____BLANK____);
		assignmentAppend(val);
		assignmentAppend(____BLANK____);
		return this;
	}

	/**
	 * 等于
	 *
	 * @param column      列表名
	 * @param otherColumn 其他的列表名称
	 * @return
	 */
	public <____T____, ____R____> MybatisPlusBuild eq(ColumnName<____T____, ____R____> column, ColumnName<____T____, ____R____> otherColumn) {
		link(column, ____EQ____, otherColumn);
		return this;
	}

	/**
	 * 不等于
	 *
	 * @param column 列表名
	 * @param val    值
	 * @return
	 */
	public <____T____, ____R____> MybatisPlusBuild neq(ColumnName<____T____, ____R____> column, Object val) {
		link(column, ____NEQ____, val);
		return this;
	}

	/**
	 * 不等于
	 *
	 * @param column      列表名
	 * @param otherColumn 其他的列表名称
	 * @return
	 */
	public <____T____, ____R____> MybatisPlusBuild neq(ColumnName<____T____, ____R____> column, ColumnName<____T____, ____R____> otherColumn) {
		link(column, ____NEQ____, otherColumn);
		return this;
	}

	/**
	 * 大于
	 *
	 * @param column 列表名
	 * @param val    值
	 * @return
	 */
	public <____T____, ____R____> MybatisPlusBuild gt(ColumnName<____T____, ____R____> column, Object val) {
		link(column, ____GT____, val);
		return this;
	}

	/**
	 * 大于
	 *
	 * @param column      列表名
	 * @param otherColumn 其他的列表名称
	 * @return
	 */
	public <____T____, ____R____> MybatisPlusBuild gt(ColumnName<____T____, ____R____> column, ColumnName<____T____, ____R____> otherColumn) {
		link(column, ____GT____, otherColumn);
		return this;
	}

	/**
	 * 大于等于
	 *
	 * @param column 列表名
	 * @param val    值
	 * @return
	 */
	public <____T____, ____R____> MybatisPlusBuild gte(ColumnName<____T____, ____R____> column, Object val) {
		link(column, ____GTE____, val);
		return this;
	}

	/**
	 * 大于等于
	 *
	 * @param column      列表名
	 * @param otherColumn 其他的列表名称
	 * @return
	 */
	public <____T____, ____R____> MybatisPlusBuild gte(ColumnName<____T____, ____R____> column, ColumnName<____T____, ____R____> otherColumn) {
		link(column, ____GTE____, otherColumn);
		return this;
	}

	/**
	 * 小于
	 *
	 * @param column 列表名
	 * @param val    值
	 * @return
	 */
	public <____T____, ____R____> MybatisPlusBuild lt(ColumnName<____T____, ____R____> column, Object val) {
		link(column, ____LT____, val);
		return this;
	}

	/**
	 * 小于
	 *
	 * @param column      列表名
	 * @param otherColumn 其他的列表名称
	 * @return
	 */
	public <____T____, ____R____> MybatisPlusBuild lt(ColumnName<____T____, ____R____> column, ColumnName<____T____, ____R____> otherColumn) {
		link(column, ____LT____, otherColumn);
		return this;
	}

	/**
	 * 小于等于
	 *
	 * @param column 列表名
	 * @param val    值
	 * @return
	 */
	public <____T____, ____R____> MybatisPlusBuild lte(ColumnName<____T____, ____R____> column, Object val) {
		link(column, ____LTE____, val);
		return this;
	}

	/**
	 * 小于等于
	 *
	 * @param column      列表名
	 * @param otherColumn 其他的列表名称
	 * @return
	 */
	public <____T____, ____R____> MybatisPlusBuild lte(ColumnName<____T____, ____R____> column, ColumnName<____T____, ____R____> otherColumn) {
		link(column, ____LTE____, otherColumn);
		return this;
	}

	/**
	 * 是null
	 *
	 * @param column 列表名
	 * @return
	 */
	public <____T____, ____R____> MybatisPlusBuild isNull(ColumnName<____T____, ____R____> column) {
		link(column, ____ISNULL____, ____NULL____);
		return this;
	}

	/**
	 * 不是null
	 *
	 * @param column 列表名
	 * @return
	 */
	public <____T____, ____R____> MybatisPlusBuild isNotNull(ColumnName<____T____, ____R____> column) {
		link(column, ____ISNOTNULL____, ____NULL____);
		return this;
	}

	/**
	 * 开始添加组
	 *
	 * @return
	 */
	public MybatisPlusBuild groupBefore() {
		append(____GROUPBEFORE____);
		return this;
	}

	/**
	 * 结束添加组
	 *
	 * @return
	 */
	public MybatisPlusBuild groupAfter() {
		append(____GROUPAFTER____);
		return this;
	}

	/**
	 * 连接字符串
	 *
	 * @return
	 */
	public MybatisPlusBuild or() {
		append(____OR____);
		return this;
	}

	/**
	 * 范围取值
	 *
	 * @param column 列表名
	 * @param start  开始的范围
	 * @param end    结束的范围
	 * @return
	 */
	public <____T____, ____R____, ____K____> MybatisPlusBuild between(ColumnName<____T____, ____R____> column, ____K____ start, ____K____ end) {
		Objects.requireNonNull(start);
		Objects.requireNonNull(end);
		StringBuilder columnBuild = getColumnBuild(column);

		if (columnBuild.length() != 0) {

			and();

			if (isStrLink(start.getClass().getName())) {
				append(String.format(____BETWEEN____, columnBuild.toString(), ("'" + getDateStr(start) + "'").intern(), ("'" + getDateStr(end) + "'").intern()));
			} else {
				append(String.format(____BETWEEN____, columnBuild.toString(), start, end));

			}
			____isWipeWhereFlag____ = Boolean.FALSE;
		}
		return this;
	}

	/**
	 * 分组
	 *
	 * @param columns 列表名
	 * @return
	 */
	public <____T____, ____R____> MybatisPlusBuild groupBy(ColumnName<____T____, ____R____>... columns) {

		StringBuilder columnBuild = getColumnBuild(columns);
		if (columnBuild.length() != 0) {

			append(String.format(____GROUPBY____, columnBuild.toString()));
		}
		return this;
	}

	/**
	 * 排序
	 *
	 * @param builds 构建排序的构建
	 * @return
	 */
	public MybatisPlusBuild orderBy(OrderBuild... builds) {
		Objects.requireNonNull(builds);


		StringBuilder orderByBuild = new StringBuilder();
		for (OrderBuild build : builds) {
			if (orderByBuild.length() > 1) {
				orderByBuild.append(____SPLIT_SIGN____);
			}

			orderByBuild.append(getColumnName(build.getColumn()).getColumnName());
			orderByBuild.append(____BLANK____);
			orderByBuild.append(build.getOrder().getDescValue());

		}

		if (orderByBuild.length() != 0) {

			append(String.format(____ORDERBY____, orderByBuild.toString()));
		}
		return this;
	}

	public <____T____, ____R____> MybatisPlusBuild notIn(ColumnName<____T____, ____R____> column, Object... ranges) {
		appendInAndNotIn(column, ____NOT_IN____, ranges);
		return this;
	}

	private <____T____, ____R____> void appendInAndNotIn(ColumnName<____T____, ____R____> column, String arith, Object... ranges) {
		and();

		String fields = getColumnName(column).getColumnName();
		StringBuilder rangeBuild = new StringBuilder();

		Object firstValFlag = ranges[0];


		if (ranges.length == 1 && firstValFlag instanceof List) {

			List list = (List) firstValFlag;

			for (Object obj : list) {
				if (rangeBuild.length() > 0) {
					rangeBuild.append(____SPLIT_SIGN____);
				}

				if (isStrLink(obj.getClass().getName())) {
					rangeBuild.append("'");
					rangeBuild.append(getDateStr(obj));
					rangeBuild.append("'");

				} else {
					rangeBuild.append(obj);
				}
			}

		} else {
			for (Object obj : ranges) {
				if (rangeBuild.length() > 0) {
					rangeBuild.append(____SPLIT_SIGN____);
				}
				if (isStrLink(obj.getClass().getName())) {
					rangeBuild.append("'");
					rangeBuild.append(getDateStr(obj));
					rangeBuild.append("'");

				} else {
					rangeBuild.append(obj);
				}
			}
		}


		append(String.format(arith, fields, rangeBuild.toString()));
		____isWipeWhereFlag____ = Boolean.FALSE;

	}

	public <____T____, ____R____> MybatisPlusBuild
	in(ColumnName<____T____, ____R____> column, Object... ranges) {

		appendInAndNotIn(column, ____IN____, ranges);

		return this;


	}

	/**
	 * 是否是字符串的连接
	 *
	 * @param className 类的名称
	 * @return
	 */
	private boolean isStrLink(String className) {
		return className.equals("java.lang.String") || className.equals("java.util.Date") || className.equals("java.time.LocalTime")
			|| className.equals("java.time.LocalDate") || className.equals("java.time.LocalDateTime");


	}

	/**
	 * 特定总数查询
	 *
	 * @param column 总数字段的名称
	 * @return
	 */
	public <____T____, ____R____> MybatisPlusBuild count(ColumnName<____T____, ____R____> column) {
		____countColumn____ = getColumnName(column).getColumnName();

		return this;
	}

	/**
	 * 是否使用cache
	 *
	 * @return
	 */
	public MybatisPlusBuild cached() {
		____useCache____.set(Boolean.TRUE);
		return this;
	}

	/**
	 * 获取cache的设置情况
	 *
	 * @return
	 */
	public Boolean isCached() {
		Boolean cacheFlag = ____useCache____.get();
		____useCache____.remove();
		return cacheFlag;
	}

	/**
	 * 获取总数的名称
	 *
	 * @return
	 */
	public String getCountColumn() {
		return ____countColumn____;
	}

	/**
	 * 获得列名的build
	 *
	 * @param columns
	 * @return
	 */
	private <____T____, ____R____> StringBuilder getColumnBuild(ColumnName<____T____, ____R____>... columns) {
		Objects.requireNonNull(columns);

		StringBuilder columnBuild = new StringBuilder(columns.length << 1);
		String column;
		for (ColumnName columnName : columns) {
			column = getColumnName(columnName).getColumnName();
			if (column == null) {
				continue;
			}
			if (columnBuild.length() > 1) {
				columnBuild.append(____SPLIT_SIGN____);
			}

			columnBuild.append(column);
		}
		return columnBuild;
	}

	/**
	 * 模糊查询
	 *
	 * @param column 模糊的列明
	 * @param val    模糊的值 格式有%val,val%,val(不写默认全模糊查询)
	 * @return
	 */
	public <____T____, ____R____> MybatisPlusBuild like(ColumnName<____T____, ____R____> column, String val) {
		StringBuilder valBuild = new StringBuilder();
		if (val.contains(____LIKE_SIGN____)) {
			valBuild.append(val);
		} else {

			valBuild.append(____LIKE_SIGN____);
			valBuild.append(val);
			valBuild.append(____LIKE_SIGN____);
		}
		link(column, ____LIKE____, valBuild.toString());
		return this;
	}

	/**
	 * 链接
	 *
	 * @param column 列表的名称
	 * @param arith  运算
	 * @param val    值
	 */
	private <____T____, ____R____> void link(ColumnName<____T____, ____R____> column, String arith, Object val) {

		Objects.requireNonNull(val);

		String columnName = getColumnName(column).getColumnName();

		if (columnName.isEmpty()) {
			return;
		}

		and();

		append("`");
		append(columnName);
		append("` ");
		append(arith);
		append(" ");


		if (val instanceof ColumnName) {
			append("`");
			append(getColumnName((ColumnName<____T____, ____R____>) val).getColumnName());
			append("` ");

		} else {
			if (!val.equals(____NULL____) && isStrLink(val.getClass().getName())) {
				append("'");
				append(getDateStr(val));
				append("'");

			} else {
				append(val);
			}

		}


		____isWipeWhereFlag____ = Boolean.FALSE;

	}

	/**
	 * 获取列名
	 *
	 * @param column lambel 表达式
	 * @return
	 */
	private <____T____, ____R____> FieldColumn getColumnName(ColumnName<____T____, ____R____> column) {
		Objects.requireNonNull(column);

		FieldColumn fieldCloumn = null;
		try {

			Class superClass = ____buildClass____;

			Method writeReplace = column.getClass().getDeclaredMethod("writeReplace");

			writeReplace.setAccessible(Boolean.TRUE);

			SerializedLambda serializedLambda = (SerializedLambda) writeReplace.invoke(column);

			String method = serializedLambda.getImplMethodName();

			String paramCacheKey = (serializedLambda.getImplClass() + method).intern();

			fieldCloumn = ____paramCache____.get(paramCacheKey);

			if (fieldCloumn == null) {

				fieldCloumn = new FieldColumn();

				List<Field> fields = MybatisPlusUtil.getAllFields(superClass);

				Field matchField = getMatchField(fields, method);
				if (matchField == null) {
					return fieldCloumn;
				}
				fieldCloumn.setColumnName(getColumnNameByField(matchField));
				fieldCloumn.setField(matchField);

				if (!fieldCloumn.isEmpty()) {
					____paramCache____.put(paramCacheKey, fieldCloumn);
				}


			}


		} catch (Exception e) {
			fieldCloumn = new FieldColumn();
		}

		return fieldCloumn;
	}


	/**
	 * 列的名称记录
	 */
	private class FieldColumn {
		private String columnName;
		private Field field;

		public String getColumnName() {
			return columnName == null ? ____EMPTY____ : columnName;
		}

		public void setColumnName(String columnName) {
			this.columnName = columnName;
		}

		public Field getField() {
			return field;
		}

		public void setField(Field field) {
			this.field = field;
		}

		public boolean isEmpty() {
			return columnName == null || columnName.isEmpty() || field == null;
		}
	}


	/**
	 * 根据方法名称获取符合的字段
	 *
	 * @param fields     字段集合
	 * @param methodName 方法名称
	 */
	private Field getMatchField(List<Field> fields, String methodName) {

		Field matchField = null;

		for (Field field : fields) {

			if (getMethodName(field).equals(methodName)) {
				matchField = field;
				break;
			}


		}
		return matchField;

	}

	/**
	 * 根据字段名获取列名
	 *
	 * @param field 字段
	 */
	private String getColumnNameByField(Field field) {
		return MybatisPlusUtil.field2ColumnName(field);

	}

	/**
	 * 获取get方法
	 *
	 * @param field 属性名
	 */
	private String getMethodName(Field field) {
		String fieldName = field.getName();
		String getMethodName = ____filed2GetMethodNameCache____.get(fieldName);
		if (getMethodName == null) {
			getMethodName = (field.getType().equals("boolean")
				? "is" : "get") + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
			____filed2GetMethodNameCache____.put(fieldName, getMethodName);
		}


		return getMethodName;
	}


	/**
	 * and连接符 默认是and
	 *
	 * @return
	 */
	public MybatisPlusBuild and() {
		boolean isStartFlag = ____sqlConditionBuild____.length() != ____WHERE____.length()
			&& (____sqlConditionBuild____.length() != (____WHERE____ + ____GROUPBEFORE____).length());

		if (isStartFlag && !____sqlConditionBuild____.toString().endsWith(____OR____)) {
			append(____AND____);
		}

		return this;
	}

	/**
	 * 页数
	 *
	 * @param start 开始页数 默认第一页开始
	 * @param count 每页返回的数目
	 * @return
	 */
	public MybatisPlusBuild page(Integer start, Integer count) {
		append(String.format(____LIMIT____, ((start <= 1 ? 1 : start) - 1) * count, count));
		return this;
	}

	public void link(String sql) {
		append(" ");
		append(sql);
		append(" ");
	}

	/**
	 * 获取构建的实体类型
	 *
	 * @return
	 */
	public Class<?> getBuildClass() {
		return ____buildClass____;
	}

	/**
	 * 构建sql
	 *
	 * @return
	 */
	public String build() {
		String build = ____sqlConditionBuild____.toString();
		if (build.startsWith(____EXTRA_WHERE____)) {
			build = build.replaceAll(____WHERE____, ____EMPTY____);
		}
		if (____pattern____.matcher(build).find()) {
			//去除多余limit
			build = build.replaceAll("LIMIT \\d+,\\d+", ____EMPTY____);
		}


		if (build.equals(____WHERE____)) {
			build = ____EMPTY____;

		}

		if (____isWipeWhereFlag____) {
			build = build.replaceAll(____WHERE____, ____EMPTY____);
		}

		return build;
	}


	/**
	 * 返回分配的构建
	 *
	 * @return
	 */
	public String assignmentBuild() {
		return ____sqlAssigmentBuild____.toString();
	}

	/**
	 * 添加赋值条件
	 *
	 * @param content 需要添加的内容
	 */
	private void assignmentAppend(Object content) {
		this.____sqlAssigmentBuild____.append(content);

	}


	/**
	 * 添加元素 用户记录初始元素的位置
	 *
	 * @param content 需要添加的内容
	 */
	private void append(Object content) {
		boolean isInsertOrUpdateFlag = (content.toString().equals(____OR____) || content.toString().equals(____AND____))
			&& ____sqlConditionBuild____.toString().endsWith(____GROUPBEFORE____);
		if (isInsertOrUpdateFlag) {
			//排除下个链接是and条件
			if (!content.toString().equals(____AND____) && ____sqlConditionBuild____.toString().endsWith(____GROUPBEFORE____)) {

				____sqlConditionBuild____.insert(____sqlConditionBuild____.length() - ____GROUPBEFORE____.length(), content);
			}
		} else {

			____sqlConditionBuild____.append(content);
		}
	}

	/**
	 * 获取日期的字符串形式
	 *
	 * @param date 日期
	 * @return
	 */
	private String getDateStr(Object date) {
		String result;
		if (date instanceof Date) {
			result = ____dateTimeFormatter____.format(LocalDateTime.ofInstant(((Date) date).toInstant(), ZoneId.systemDefault()));
		} else if (date instanceof LocalDateTime) {
			result = ____dateTimeFormatter____.format((LocalDateTime) date);

		} else if (date instanceof LocalDate) {
			result = ____dateFormatter____.format((LocalDate) date);

		} else if (date instanceof LocalTime) {
			result = ____timeFormatter____.format((LocalTime) date);

		} else {
			result = date.toString();

		}
		return result;

	}


	private enum ORDER {
		ASC("ASC"), DESC("DESC");
		private String descValue;

		ORDER(String descValue) {
			this.descValue = descValue;
		}

		public String getDescValue() {
			return descValue;
		}
	}

	public enum Arithmetic {

		ADD("+"), DIVIDE("/"), multiply("*"), SUBTRACT("-");
		private String symbol;

		Arithmetic(String symbol) {

			this.symbol = symbol;
		}

		public String getSymbol() {
			return symbol;
		}
	}


	/**
	 * Column的列名
	 */


	public interface ColumnName<____T____, ____R____> extends Serializable {
		____R____ column(____T____ t);
	}

	/**
	 * 排序的构建
	 */
	public static class OrderBuild<____T____, ____R____> {
		private ColumnName<____T____, ____R____> column;
		private ORDER order;

		private OrderBuild(ColumnName<____T____, ____R____> column, ORDER order) {
			this.column = column;
			this.order = order;
		}

		public static <____T____, ____R____> OrderBuild buildAsc(ColumnName<____T____, ____R____> column) {
			return new OrderBuild(column, ORDER.ASC);
		}

		public static <____T____, ____R____> OrderBuild buildDesc(ColumnName<____T____, ____R____> column) {
			return new OrderBuild(column, ORDER.DESC);
		}

		public ColumnName<____T____, ____R____> getColumn() {
			return column;
		}

		public void setColumn(ColumnName<____T____, ____R____> column) {
			this.column = column;
		}

		public ORDER getOrder() {
			return order;
		}

		public void setOrder(ORDER order) {
			this.order = order;
		}

	}


}
